<template>
  <div class="page-service-group">
    <Breadcrumb separator=">">
      <BreadcrumbItem :to="'/home/environment/' + $route.params.environmentId + '/info'">
        <Tooltip :content="'环境（' + envName + '）'" placement="top">
          <i class="ivu-icon ivu-icon-aperture"></i> {{envName}}
        </Tooltip>
      </BreadcrumbItem>
      <BreadcrumbItem
        :to="'/home/environment/' + $route.params.environmentId + '/info/' + $route.params.groupId">
        <Tooltip :content="'服务组（' + groupName + '）'" placement="top">
          <i class="ivu-icon ivu-icon-ribbon-b"></i> {{groupName}}
        </Tooltip>
      </BreadcrumbItem>
      <BreadcrumbItem>
        <Tooltip :content="'服务（' + service.id + '）'" placement="top">{{service.id}}</Tooltip>
      </BreadcrumbItem>
    </Breadcrumb>

    <h4 class="zl-title">基本信息
      <div class="button-inner fr" @click="serviceEdit" v-if="hasPermission($store, $route.params.environmentId, 'SERVICE_DELETE_ENV|GROUP') && service.id != 'mysql' && (service.type !== 'statefulSet' && (service.status == 'active' || service.status == 'inactive' || service.status == 'degrade'))">
        <Icon type="ios-create-outline" class="env-edit"></Icon> 编辑服务
      </div>
    </h4>
    <div class="environment-info">
      <Spin fix v-if="isLoading"></Spin>
      <div class="environment-info-box" v-else>
        <Row :gutter="10">
          <Col span="6" class="f-nowrap"><span class="info-title">名称：</span>{{service.id}}</Col>
          <Col span="6" class="f-nowrap"><span class="info-title">状态：</span>
            <span v-if="service.status === 'active'" class="color-green">启用</span>
            <span v-else class="color-red">停用</span>
          </Col>
          <Col span="12"><span class="info-title">镜像地址：</span>{{service.image}}</Col>
          <Col span="6"><span class="info-title">容器数：</span>{{service.replicas}}</Col>
          <Col span="6"><span class="info-title">单节点服务：</span>
            <span v-if="service.replicas === 1">是</span>
            <span v-else>否</span>
          </Col>
          <Col span="12"><span class="info-title">启动策略：</span>{{service.restartPolicy}}</Col>
          <Col span="6"><span class="info-title">创建时间：</span>{{service.creationTimestamp}}</Col>
          <Col span="8" v-if="service.clusterIP"><span class="info-title">集群IP：</span>{{service.clusterIP}}</Col>
        </Row>
      </div>
    </div>

    <div class="u-fold-all">
      <Button type="primary" size="small" @click="foldAll" v-if="!isFoldAll">
        <Icon type="ios-arrow-down" /> 全部展开
      </Button>
      <Button type="primary" size="small" @click="unfoldAll" v-if="isFoldAll">
        <Icon type="ios-arrow-up" /> 全部收起
      </Button>
    </div>

    <div class="panel" :class="{'active': toggleLabel.port}" v-if="service.ports && service.ports.length > 0">
      <h4 class="title-detail" @click="toggle('port')">
        <Icon type="ios-arrow-forward" />端口映射
      </h4>
      <Row :gutter="10" v-for="(port, portIndex) in service.ports" :key="portIndex">
        <Col span="3">容器端口：{{port.targetPort}}</Col>
        <Col span="4">服务端口: {{port.port}}</Col>
        <Col span="3">协议：{{port.protocol}}</Col>
      </Row>
    </div>
    <div class="panel" :class="{'active': toggleLabel.env}" v-if="service.env && service.env.length > 0">
      <h4 class="title-detail" @click="toggle('env')">
        <Icon type="ios-arrow-forward" />环境变量
      </h4>
      <Row :gutter="10" v-for="(env, envIndex) in service.env" :key="envIndex">
        <Col span="6" class="f-nowrap">键：{{env.name}}</Col>
        <Col span="18">值：{{env.value}}</Col>
      </Row>
    </div>
    <div class="panel" :class="{'active': toggleLabel.command}" v-if="service.command">
      <h4 class="title-detail" @click="toggle('command')">
        <Icon type="ios-arrow-forward" />命令
      </h4>
      <Row :gutter="10">
        <Col span="6">命令：{{service.command}}</Col>
        <Col span="18">参数：{{service.args}}</Col>
      </Row>
    </div>
    <div class="panel" :class="{'active': toggleLabel.config}" v-if="service.configMapName">
      <h4 class="title-detail" @click="toggle('config')">
        <Icon type="ios-arrow-forward" />配置集
      </h4>
      <Row :gutter="10">
        <Col span="6">配置集:
          <span class="zl-link-click"  v-if="hasPermission($store, $route.params.environmentId, 'SERVICE_PATCH_ENV|GROUP')" @click="configDetail(service.configMapName)">{{service.configMapName}}
            <Icon type="ios-create-outline"></Icon>
          </span>
        </Col>
        <Col span="18">挂载路径: {{service.configMapMountPath}}</Col>
      </Row>
    </div>
    <div class="panel" :class="{'active': toggleLabel.pvc}" v-if="service.pvcName">
      <h4 class="title-detail" @click="toggle('pvc')">
        <Icon type="ios-arrow-forward" />存储卷
      </h4>
      <Row :gutter="10">
        <Col span="6">存储卷：
          <span class="zl-link-click" v-if="hasPermission($store, $route.params.environmentId, 'SERVICE_PATCH_ENV|GROUP')" @click="pvcDetail(service.pvcName)">
            {{service.pvcName}}
          </span>
        </Col>
        <Col span="18">挂载路径: {{service.mountPath}}</Col>
      </Row>
    </div>
    <div class="panel" :class="{'active': toggleLabel.resource}" v-if="service.cpu || service.requestCpu || service.requestMemory || service.memory">
      <h4 class="title-detail" @click="toggle('resource')">
        <Icon type="ios-arrow-forward" />资源配额
      </h4>
      <Row :gutter="10">
        <Col span="6" v-if="service.requestCpu">容器CPU最小值(mCpu): {{service.requestCpu}}</Col>
        <Col span="6" v-if="service.cpu">容器CPU最大值(mCpu): {{service.cpu}}</Col>
        <Col span="6" v-if="service.requestMemory">容器内存最小值(Gi): {{service.requestMemory}}</Col>
        <Col span="6" v-if="service.memory">容器内存最大值(Gi): {{service.memory}}</Col>
      </Row>
    </div>

    <!-- 容器列表 -->
    <h4 class="zl-title">容器列表
      <div class="fr">
        <search placeholder="容器名" @change="searchPods"></search>
        <Button type="primary" @click="podCount(1)" class="button-add" :loading="isAddLoading"
          v-if="hasPermission($store, $route.params.environmentId, 'SERVICE_PATCH_ENV|GROUP') && service.status === 'active'">
          <Icon type="md-add"></Icon>
          <span class="button-name">添加容器</span>
        </Button>
        <Button type="warning" @click="podCount(-1)" class="button-add" :loading="isMinusLoading" :disabled="podList.length <= 0"
          v-if="hasPermission($store, $route.params.environmentId, 'SERVICE_PATCH_ENV|GROUP') && service.status === 'active'">
          <Icon type="md-remove"></Icon>
          <span class="button-name">减少容器</span>
        </Button>
      </div>
    </h4>
    <div class="zl-page-loading" v-if="isLoading">
      <Spin class="zl-page-loading" fix></Spin>
    </div>
    <Table :columns="columns" :data="podList" class="pod-table" v-else></Table>

    <!-- 容器日志弹窗 -->
    <pod-log-modal :visible.sync="podLogVisible" :form="podForm" :wsUrl="wsUrl" ></pod-log-modal>

    <!-- 容器详情弹窗 -->
    <pod-detail-modal :visible.sync="podDetailVisible" :form="podForm"></pod-detail-modal>

    <!-- 容器编辑 -->
    <service-add-modal :visible.sync="serviceAddVisible" :params="serviceParams" @finish="getServiceInfo"></service-add-modal>

    <!-- 配置集编辑 -->
    <add-modify-model :visible.sync="configVisible" :form="configForm" @finish="getServiceInfo" ></add-modify-model>

    <!-- 存储卷详情 -->
    <pvc-detail-model :visible.sync="pvcDetailVisible" :form="pvcForm"></pvc-detail-model>



  </div>
</template>

<script>
  import Search from '@/components/search'
  import Fetch from '@/api/request'
  import PodLogModal from '@/components/service/pod-log-modal'
  import PodDetailModal from '@/components/service/pod-detail-modal'
  import { downloadImg } from '@/utils'
  import ServiceAddModal from '@/components/add-service/modal'
  import AddModifyModel from '@/components/config-set/add-modify-model'
  import PvcDetailModel from '@/components/pvc/detail-model'

  export default {
    name: 'service',
    components: {Search, PodLogModal, PodDetailModal, ServiceAddModal, AddModifyModel, PvcDetailModel},
    data() {
      return {
        serviceId: '',
        service: {},
        envName: '',
        groupName: '',
        isLoading: true,
        isAddLoading: false,
        isMinusLoading: false,
        podList: [],
        podListBack: [],
        serviceAddVisible: false,
        configVisible: false,
        pvcDetailVisible: false,
        configForm: {},
        pvcForm: {},
        columns: [{
          type: 'index',
          width: 60
        }, {
          title: '状态',
          width: 50,
          render: (h, params) => {
            return h('i', {
              class: params.row.status.phase === 'Running' ? 'zl-badge' : 'zl-badge badge-error'
            })
          }
        }, {
          title: '名称',
          render: (h, params) => {
            return h('div', {
              class: 'zl-link',
              on: {
                click: () => {
                  this.podDetail(params.row)
                }
              }
            }, params.row.id)
          }
        }, {
          title: 'IP地址',
          render: (h, params) => {
            return h('span', params.row.status.podIP)
          }
        }, {
          title: '操作',
          align: 'center',
          width: 500,
          render: (h, params) => {
            let btnList = [h('div', {
              class: 'button-inner',
              on: {
                click: () => {
                  this.podLog(params.row)
                }
              }
            }, [
              h('Icon', {
                props: {
                  type: 'ios-paper'
                }
              }, ''),
              '日志'
            ])]
            if (this.hasPermission(this.$store, this.$route.params.environmentId, 'POD_DELETE_ENV|POD')) {
              btnList.push(h('div', {
                class: 'button-inner',
                on: {
                  click: () => {
                    this.podDelete(params.row)
                  }
                }
              }, [
                h('Icon', {
                  props: {
                    type: 'md-trash'
                  }
                }, ''),
                '删除'
              ]))
            }
            // javaAppFlag判断是否是java程序
            if (this.hasPermission(this.$store, this.$route.params.environmentId, 'SERVICE_PATCH_ENV|GROUP') && params.row.javaAppFlag === 0) {
              btnList.push(h('Dropdown', {
                class: 'button-inner',
                attrs: {
                  trigger: 'click'
                }
              }, [
                h('div', {
                  class: 'button-inner'
                }, [
                  h('Icon', {
                    props: {
                      type: 'md-download'
                    }
                  }, ''),
                  '下载'
                ]),
                h('DropdownMenu', {
                  slot: 'list'
                }, [
                  h('DropdownItem', [h('div', {
                    class: 'button-inner',
                    on: {
                      click: () => {
                        this.threadDumpDownload(params.row)
                      }
                    }
                  }, [
                    h('Icon', {
                      props: {
                        type: 'md-download'
                      }
                    }, ''),
                    '线程块下载'
                  ])]),
                  h('DropdownItem', [h('div', {
                    class: 'button-inner',
                    on: {
                      click: () => {
                        this.heapDumpDownload(params.row)
                      }
                    }
                  }, [
                    h('Icon', {
                      props: {
                        type: 'md-download'
                      }
                    }, ''),
                    '内存块下载'
                  ])]),
                  h('DropdownItem', [h('div', {
                    class: 'button-inner',
                    on: {
                      click: () => {
                        this.heapUsageDownload(params.row)
                      }
                    }
                  }, [
                    h('Icon', {
                      props: {
                        type: 'md-download'
                      }
                    }, ''),
                    '内存使用情况下载'
                  ])])
                ])
              ]))
            }
            return h('div', btnList)
          }
        }],
        prePodNum: -1, // 用于在改变容器数量时保存改变前容器数量值
        podLogVisible: false,
        podForm: {},
        podDetailVisible: false,
        wsUrl: '',
        toggleLabel: {
          port: false,
          env: false,
          command: false,
          config: false,
          pvc: false,
          resource: false
        },
        isHeapDownloading: [],
        isThreadDownloading: [],
        isHeapUsageDownloading: [],
        url: '',
        serviceParams: {},
        isFoldAll: false
      }
    },
    mounted() {
      let vm = this
      vm.$nextTick(function () {
        vm.groupName = localStorage.getItem('groupName')
        vm.envName = JSON.parse(localStorage.getItem('envionmentSelect')).environmentName
        vm.init()
      })
    },
    methods: {
      // 全部展开
      foldAll() {
        this.isFoldAll = true
        for (const key in this.toggleLabel) {
          if (this.toggleLabel.hasOwnProperty(key)) {
            this.toggleLabel[key] = true
          }
        }
      },
      unfoldAll() {
        this.isFoldAll = false
        for (const key in this.toggleLabel) {
          if (this.toggleLabel.hasOwnProperty(key)) {
            this.toggleLabel[key] = false
          }
        }
      },
      // 查看pvc详情
      pvcDetail(name) {
        Fetch.get({
          url: '/api/environments/' + this.$route.params.environmentId + '/persistentvolumeclaims'
        }).then((res) => {
          for (let i = 0; i < res.data.length; i++) {
            const pvc = res.data[i]
            if (pvc.id === name) {
              this.pvcForm = pvc
              break
            }
          }
          if (this.pvcForm && this.pvcForm.id) {
            this.pvcDetailVisible = true
          }
        })
      },
      // 编辑配置集
      configDetail(name) {
        Fetch.get({
          url: '/api/environments/' + this.$route.params.environmentId + '/configmaps/' + name
        }).then((res) => {
          this.configForm = res.data
          this.configVisible = true
        })
      },
      // 服务编辑
      serviceEdit() {
         // 获取访问权
        Fetch.get({
          url: '/api/environments/' + this.$route.params.environmentId + '/ingresses'
        }).then((res) => {
          for (let i = 0; i < res.data.length; i++) {
            const access = res.data[i]
            for (let j = 0; j < access.paths.length; j++) {
              const path = access.paths[j]
              if (path.serviceId === this.service.id || access.serviceId === this.service.id + '-management') {
                this.$set(this.service, 'access', Object.assign({serviceId: path.serviceId, link: 'http://' + access.host + path.path}, access))
              }
            }
          }
          this.serviceParams = {
            groupId: this.$route.params.groupId,
            clone: false,
            service: Object.assign({}, this.service)
          }
          this.serviceAddVisible = true
        })
      },
      // 线程块下载
      threadDumpDownload(row) {
        if (this.isThreadDownloading.indexOf(row.id) !== -1) {
          this.$Message.warning({
            content: '正在下载中，请稍后再试！',
            duration: this.DURATION
          })
          return
        }
        this.isThreadDownloading.push(row.id)
        Fetch.get({
          url: '/api/jvm/threadDump/' + this.$route.params.environmentId + '/' + row.id,
          self: 'then',
          done: () => {
            this.isThreadDownloading = this.isThreadDownloading.filter((downId) => {
              return downId !== row.id
            })
          }
        }).then((res) => {
          if (res.data) {
            let blob = new Blob([res.data])
            let a = document.createElement('a')
            let url = window.URL.createObjectURL(blob)
            a.href = url
            a.download = 'threadDump.txt'
            a.click()
          }
        })
      },
      // 内存块下载
      heapDumpDownload(row) {
        if (this.isHeapDownloading.indexOf(row.id) !== -1) {
          this.$Message.warning({
            content: '正在下载中，请稍后再试！',
            duration: this.DURATION
          })
          return
        }
        // 由于限制了所有用户同时只能下载3个，先判断是否能够进行下载
        Fetch.get({
          url: '/api/jvm/heapDump/checkDownCount',
          done: () => {
            this.isHeapDownloading = this.isHeapDownloading.filter((downId) => {
              return downId !== row.id
            })
          }
        }).then((res) => {
          this.isHeapDownloading.push(row.id)
          downloadImg(this.url + '/api/jvm/heapDump/' + this.$route.params.environmentId + '/' + row.id + '?token=' + this.$cookie.get('token'))
        })
      },
      // 内存使用率下载
      heapUsageDownload(row) {
        if (this.isHeapUsageDownloading.indexOf(row.id) !== -1) {
          this.$Message.warning({
            content: '正在下载中，请稍后再试！',
            duration: this.DURATION
          })
          return
        }
        this.isHeapUsageDownloading.push(row.id)
        Fetch.get({
          url: '/api/jvm/heapUsage/' + this.$route.params.environmentId + '/' + row.id,
          self: 'then',
          done: () => {
            this.isHeapUsageDownloading = this.isHeapUsageDownloading.filter((downId) => {
              return downId !== row.id
            })
          }
        }).then((res) => {
          if (res.data) {
            let blob = new Blob([res.data])
            let a = document.createElement('a')
            let url = window.URL.createObjectURL(blob)
            a.href = url
            a.download = 'heapUsage.txt'
            a.click()
          }
        })
      },
      // 展开收起详细信息
      toggle(label) {
        this.toggleLabel[label] = !this.toggleLabel[label]
      },
      // 打开容器详情弹窗
      podDetail(pod) {
        this.podForm = {id: pod.id}
        this.podDetailVisible = true
      },
      // 打开容器日志弹窗
      podLog(pod) {
        this.podForm = Object.assign({logs: ''}, {id: pod.id})
        this.podLogVisible = true
      },
      // 初始化
      init() {
        this.getServiceInfo()
        this.getPods()
      },
      // 获取服务基本信息
      getServiceInfo() {
        Fetch.get({
          url: '/api/service/info',
          params: {
            environmentId: this.$route.params.environmentId,
            serviceId: this.$route.params.serviceId,
            groupId: this.$route.params.groupId
          }
        }).then((res) => {
          this.service = res.data
          this.wsUrl = res.url.replace(/http(s?):\/\//gi, '') + '/webSocket/podLog'
        })
      },
      // 获取服务下容器信息
      getPods() {
        Fetch.get({
          url: '/api/getPods',
          params: {
            environmentId: this.$route.params.environmentId,
            groupId: this.$route.params.groupId,
            serviceId: this.$route.params.serviceId
          },
          done: () => {
            this.isLoading = false
          }
        }).then((res) => {
          this.podList = res.data
          this.url = res.url
          if (this.podList.length === this.prePodNum) {
            setTimeout(() => {
              this.getPods()
            }, 2000)
          }
          this.podListBack = res.data
        })
      },
      podDelete(pod) {
        this.$Modal.confirm({
          title: '系统提示',
          content: '<div style="padding: 30px; text-align: center;">确定删除容器（' + pod.id + '）？</div>',
          loading: true,
          width: 500,
          onOk: () => {
            Fetch.delete({
              url: '/api/pod/delete',
              params: {
                environmentId: this.$route.params.environmentId,
                podId: pod.id
              },
              done: () => {
                this.$Modal.remove()
              }
            }).then((res) => {
              this.$Message.success({
                content: '删除容器（' + pod.id + '）成功！',
                duration: this.DURATION
              })
              setTimeout(() => {
                this.getPods()
              }, 500)
            })
          }
        })
      },
      // 修改容器数量
      podCount(offset) {
        if (this.podList.length + offset === 0) {
          this.$Modal.confirm({
            title: '系统提示',
            content: '副本数为0，意味着停止该服务！',
            onOk: () => {
              this.podHandle(offset)
            }
          })
        } else {
          this.podHandle(offset)
        }
      },
      // 容器数处理
      podHandle(offset) {
        this.prePodNum = this.podList.length
        offset > 0 ? this.isAddLoading = true : this.isMinusLoading = true
        Fetch.patch({
          url: '/api/pod/add',
          params: {
            environmentId: this.$route.params.environmentId,
            groupId: this.$route.params.groupId,
            serviceId: this.$route.params.serviceId,
            data: {
              patchType: 'replicas',
              replicas: this.service.replicas + offset
            }
          },
          done: () => {
            offset > 0 ? this.isAddLoading = false : this.isMinusLoading = false
          }
        }).then((res) => {
          this.$Message.success({
            content: offset > 0 ? '新增容器成功！' : '减少容器成功！',
            duration: this.DURATION
          })
          setTimeout(() => {
            this.getPods()
          }, 1000)
        })
      },
      // 根据名称搜索服务组
      searchPods(search) {
        let temp = []
        this.podListBack.forEach((pod) => {
          let name = pod.id
          if (name.indexOf(search) !== -1) {
            temp.push(pod)
          }
        })
        this.podList = temp
      }
    }
  }
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .environment-info {
    position: relative;
    min-height: 100px;
  }
  .environment-info-box {
    position: relative;
    line-height: 32px;
    background-color: #fff;
    padding: 15px;
    border-radius: 4px;
    border: 1px solid #eee;
  }
  .modal-add {
    position: relative;
    padding: 10px 50px 10px 20px;
  }
  .button-add {
    .iconfont:hover {
      color: #fff;
    }
    + .button-add {
      margin-left: 10px;
    }
  }
  .pod-table {
    margin-top: 20px;
  }
  .title-detail {
    background-color: #fff;
    cursor: pointer;
    padding: 8px 0;
    .ivu-icon {
      transition: all 0.3s ease;
      transform: rotate(0deg);
    }
  }
  .page-service-group {
    .panel {
      margin-top: 10px;
      padding-top: 0;
      padding-bottom: 0;
      .ivu-row {
        display: none;
        border-top: 1px solid #eee;
        padding-top: 10px;
        padding-bottom: 10px;
      }
      &.active {
        .ivu-row {
          display: block;
        }
        .ivu-icon {
          transform: rotate(90deg);
        }
      }
    }
  }
  .u-fold-all {
    margin-top: 8px;
    text-align: right;
  }
  .env-edit {
    font-size: 16px;
    vertical-align: middle;
  }
</style>
